package messenger;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.util.Scanner;
import java.util.logging.Logger;

public class MessengerSession {
	private static Logger log = Logger.getLogger("MessengerSession");
	private Socket socket = null;
	private boolean isHttpProxy = false;
	private String host = null;
	private int port = 0;
	private boolean isServerSession = false;
	
	private String user = null;
	private BufferedReader reader = null;
	private PrintWriter writer = null;
	public static final String N_SERVER = "$SERVER$";
	public static final String N_SPLIT1 = "&;&";
	public static final String N_SPLIT2 = "&:&";
	
	public static final String T_MESSAGE = "$MESSAGE$";
	public static final String T_COMMAND = "$COMMAND$";
	
	public static final String A_SERVERREPLY = "$SERVERREPLY$";	
	public static final String A_LOGIN = "$LOGIN$";
	public static final String A_SEND_MESSAGE = "$SEND_MESSAGE$";
	public static final String A_GET_FRIEND = "$GET_FRIEND$";
	public static final String A_DISCONNECT = "$DISCONNECT$";
	
	public static final String R_SUCCEED = "$SUCCEED$";
	public static final String R_FAIL = "$FAIL$";
	
	public static final int WAIT = 300;
	public static final int WAITTIMES = 100;
	
	public boolean isValidMessage(String msg) {
		if(msg != null && (msg.startsWith(A_SERVERREPLY) || msg.startsWith(A_LOGIN) || 
				msg.startsWith(A_SEND_MESSAGE) || msg.startsWith(A_GET_FRIEND) || msg.startsWith(A_DISCONNECT)))
			return true;
		return false;
	}
	

	public MessengerSession(Socket socket, String user, boolean isHttpProxy, String host, int port) {
		this.socket = socket;
		this.user = user;
		this.isHttpProxy = isHttpProxy;
		this.host = host;
		this.port = port;
		try {
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		try {
			writer = new PrintWriter(socket.getOutputStream());
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void closeSession() {
		try {
			reader.close();
			writer.close();
			user = null;
			socket.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	

	public boolean sendMessage(String action, String msg, String to) {
		return sendMessage(action, msg, to, user);
	}
	
	public boolean sendMessage(String action, String msg, String to, String from) {
		try {
			StringBuilder message = new StringBuilder(action).append(N_SPLIT1).append(to).append(N_SPLIT1).
				append(from).append(N_SPLIT1).append(T_MESSAGE).append(N_SPLIT1).append(msg);
			System.out.println(message + ":[" + isHttpProxy + ":" + isServerSession + "]");
			if(isHttpProxy && !isServerSession) {
				StringBuilder sb = new StringBuilder("GET HTTP://").append(host).
				append(":").append(port).append(" HTTP/1.1");
				System.out.println(sb.toString());
				writer.println(sb.toString());
				writer.println(message);
				writer.print("\n");
				writer.flush();
			}else if(isHttpProxy && isServerSession) {
				writer.println("HTTP/1.1 200 OK");
				writer.println("Proxy-Connection: Keep-Alive");
				writer.println("Connection: Keep-Alive");
				writer.println(message);
				writer.print("\n");
				writer.flush();
			}else {
				writer.println(message);
				writer.flush();
			}
			return true;
		} catch (RuntimeException e) {
			log.severe("Send message failed!");
			return false;
		}
	}
	
	public boolean serverReply(String action, String type, String msg) {
		try {
			StringBuilder message = new StringBuilder(action).append(N_SPLIT1).append(user).append(N_SPLIT1).
				append(N_SERVER).append(N_SPLIT1).append(type).append(N_SPLIT1).append(msg);
			System.out.println(message + ":[" + isHttpProxy + "]");
			if(isHttpProxy) {
				writer.println("HTTP/1.1 200 OK");
//				writer.println("Proxy-Connection: Keep-Alive");
//				writer.println("Connection: Keep-Alive");
//				writer.println("Content-Type: text/html");
				
				
//				writer.println("Expires: Sun, 31 Aug 2009 00:24:07 GMT");
//				writer.println("Date: Sat, 31 Aug 2002 00:24:08 GMT");
//				writer.println("Transfer-Encoding: chunked");
//				writer.println("Cache-Control: private");
			}
			writer.println(message);
			if(isHttpProxy) {
//				writer.println("0");
				writer.print("\n");
			}
			writer.flush();
			System.out.println(message + ":[sent]");
			return true;
		} catch (RuntimeException e) {
			log.severe("Send message failed!");
			return false;
		}
	}

	public String receiveMessage() {
		try {
			
			int i = 0;
			
			while(true) {
				i++;
				if(reader.ready()) {
					return reader.readLine();
				}
				if(i >= WAITTIMES) {
					return null;
				}
				try {
					Thread.sleep(WAIT);
				} catch (InterruptedException e) {
					
				}
				
			}
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}


	public boolean isHttpProxy() {
		return isHttpProxy;
	}


	public void setHttpProxy(boolean isHttpProxy) {
		this.isHttpProxy = isHttpProxy;
	}


	public boolean isServerSession() {
		return isServerSession;
	}


	public void setServerSession(boolean isServerSession) {
		this.isServerSession = isServerSession;
	}

}
